#include "mainwindow.h"
#include "bluetooth.h"
#include "communication.h"
#include "tools.h"
#include "ui_mainwindow.h"
#include "xlsxdocument.h"
#include <QCheckBox>
#include <QDir>
#include <QFile>
#include <QFileDialog>
#include <QKeyEvent>
#include <QLabel>
#include <QMediaPlayer>
#include <QString>
#include <QTextToSpeech>
#include <QTranslator>
#include <QtConcurrent>
#include <Windows.h>
#include <Windowsx.h>
#include <algorithm>
#include <qtablewidget.h>

static const struct
{
    /* 基础信息 */
    const char* windowTitle = QT_TRANSLATE_NOOP("dynamic", "远程云秤");
    const char* welcome = QT_TRANSLATE_NOOP("dynamic", "欢迎使用蓝牙语音电子秤上位机软件");
    const char* statusBarPermanentLabel = QT_TRANSLATE_NOOP("dynamic", "2019040140404庞磊-毕设-2023.4.19");

    /* 蓝牙 */
    const char* connect = QT_TRANSLATE_NOOP("dynamic", "连接");
    const char* bluetoothConnection = QT_TRANSLATE_NOOP("dynamic", "蓝牙连接中...");
    const char* cancelConnect = QT_TRANSLATE_NOOP("dynamic", "取消连接");
    const char* disconnect = QT_TRANSLATE_NOOP("dynamic", "断开连接");
    const char* connecting = QT_TRANSLATE_NOOP("dynamic", "正在重新扫描蓝牙设备...");
    const char* connectionFail = QT_TRANSLATE_NOOP("dynamic", "蓝牙连接失败，未找到设备");
    const char* connectionSucceed = QT_TRANSLATE_NOOP("dynamic", "蓝牙连接成功");
    const char* disconnectBluetooth = QT_TRANSLATE_NOOP("dynamic", "已断开蓝牙连接");
    const char* failBluetoothDevice = QT_TRANSLATE_NOOP("dynamic", "无效的蓝牙设备，请重新选择");
    const char* socketError = QT_TRANSLATE_NOOP("dynamic", "蓝牙通信过程发生未知错误");
    const char* discoveryError = QT_TRANSLATE_NOOP("dynamic", "扫描蓝牙过程中发生错误");

    /* 商品 */
    const char* tableWidgetHeader[4] = { QT_TRANSLATE_NOOP("dynamic", "商品"), QT_TRANSLATE_NOOP("dynamic", "单价(y/kg)"), QT_TRANSLATE_NOOP("dynamic", "常用"), QT_TRANSLATE_NOOP("dynamic", "删除") };
    const char* addGoos = QT_TRANSLATE_NOOP("dynamic", "添加商品");
    const char* cancelAddGoos = QT_TRANSLATE_NOOP("dynamic", "取消添加");
    const char* addGoodsSucceed = QT_TRANSLATE_NOOP("dynamic", "商品添加成功");
    const char* addFreqGoods = QT_TRANSLATE_NOOP("dynamic", "添加了常用商品");
    const char* removeGoods = QT_TRANSLATE_NOOP("dynamic", "移除了商品");
    const char* removeFreqGoods = QT_TRANSLATE_NOOP("dynamic", "移除了常用商品");
    const char* pleaseChooseGoods = QT_TRANSLATE_NOOP("dynamic", "请选择一个商品后再进行操作");
    const char* failNameOrPrice = QT_TRANSLATE_NOOP("dynamic", "商品名和单价都必须填写");
    const char* failName = QT_TRANSLATE_NOOP("dynamic", "商品名字符长度不能超过 11，当前字符长度为 %1");
    const char* failPrice1 = QT_TRANSLATE_NOOP("dynamic", "价格的整数部分最多 3 位，同时小数有且只有 1 位");
    const char* failPrice2 = QT_TRANSLATE_NOOP("dynamic", "价格必须大于 0 元/克，小于 1000 元/g");
    const char* failAdd = QT_TRANSLATE_NOOP("dynamic", "不能多次添加同一商品");
    const char* loadGoods = QT_TRANSLATE_NOOP("dynamic", "正在加载商品信息...");
    const char* loadGoodsOK = QT_TRANSLATE_NOOP("dynamic", "商品信息加载完毕");
    const char* leastOneGoods = QT_TRANSLATE_NOOP("dynamic", "至少要有一个商品");
    const char* leastOneFreqUsedGoods = QT_TRANSLATE_NOOP("dynamic", "至少要有一个常用商品");

    /* 交易记录 */
    const char* transactionTableHeader[5] = { QT_TRANSLATE_NOOP("dynamic", "交易时间"), QT_TRANSLATE_NOOP("dynamic", "商品"), QT_TRANSLATE_NOOP("dynamic", "单价(y/kg)"), QT_TRANSLATE_NOOP("dynamic", "重量(kg)"), QT_TRANSLATE_NOOP("dynamic", "总价(y)") };
    const char* failSave = QT_TRANSLATE_NOOP("dynamic", "纪录保存失败，文件可能正在被占用");

    /* 主题 */
    const char* themeSelect = QT_TRANSLATE_NOOP("dynamic", "选择qss主题文件");
    const char* themeFilter = QT_TRANSLATE_NOOP("dynamic", "主题文件(*.qss);;All Files (*.*)");
    const char* languageSwitch = QT_TRANSLATE_NOOP("dynamic", "语言设置将在下次启动应用时生效");
} globalText;

const QHash<QString, QString> nameToQm =
{
    { "简体中文", "zh_CN.qm" },
    { "English", ":/language/en.qm" },
    { "日本語です", ":/language/ja.qm" },
    { "한국어", ":/language/ko.qm" }
};

const QHash<QString, QLocale::Language> nameToTtsLocal =
{
    { "简体中文", QLocale::Chinese },
    { "English", QLocale::English },
    { "日本語です", QLocale::Japanese },
    { "한국어", QLocale::Korean }
};

MainWindow::MainWindow(QWidget* parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow())
    , statusBarMessage(new QLabel())
    , player(new QMediaPlayer())
    , tts(new QTextToSpeech())
    , bluetooth(new Bluetooth())
    , socketBuf(new SocketBuf())
    , settings("settings.ini", QSettings::IniFormat)
    , transactionRecordConfig("transactionRecordConfig.ini", QSettings::IniFormat)
    , currentTheme(":/style/blue.qss")
{
    if (!settings.contains("language"))
    {
        settings.setValue("language", "简体中文");
    }
    if (settings.contains("theme"))
    {
        currentTheme = settings.value("theme").toString();
    }
    setTheme(currentTheme);

    if (!transactionRecordConfig.contains("dir"))
    {
        transactionRecordConfig.setValue("dir", "./log");
    }
    if (!transactionRecordConfig.contains("timeout"))
    {
        transactionRecordConfig.setValue("timeout", 15);
    }

    ui->setupUi(this);
    // 设置主窗口
    setWindowTitle(QCoreApplication::translate("dynamic", globalText.windowTitle));

    // 窗口位置和大小
    move(settings.value("pos").toPoint());
    resize(settings.value("width").toInt(), settings.value("height").toInt());

    // 设置蓝牙设备显示选择框一次最多显示 10 个项
    ui->bluetooth_cb->setMaxVisibleItems(10);

    // 按钮设置
    ui->Switch_pb->setAutoRepeat(true);
    ui->Switch_pb->setAutoRepeatDelay(1500);
    ui->Switch_pb->setAutoRepeatInterval(500);
    ui->Pre_pb->setAutoRepeat(true);
    ui->Pre_pb->setAutoRepeatDelay(1500);
    ui->Pre_pb->setAutoRepeatInterval(500);
    ui->Nex_pb->setAutoRepeat(true);
    ui->Nex_pb->setAutoRepeatDelay(1500);
    ui->Nex_pb->setAutoRepeatInterval(500);
    ui->Enter_pb->setAutoRepeat(true);
    ui->Enter_pb->setAutoRepeatDelay(1500);
    ui->Enter_pb->setAutoRepeatInterval(500);

    ui->powerSaving->setProperty("on", settings.value("powerSaving").toBool());

    // 信息框设置
    statusBarMessage->setParent(ui->statusbar);
    ui->statusbar->addWidget(statusBarMessage, 3);
    ui->statusbar->addPermanentWidget(new QLabel(QCoreApplication::translate("dynamic", globalText.statusBarPermanentLabel), statusBarMessage));

    // 商品输入框设置
    ui->inputTableWidget->setWindowFlags(Qt::FramelessWindowHint);
    ui->inputTableWidget->setInputMethodHints(Qt::ImhHiddenText);
    ui->inputTableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
    ui->inputTableWidget->verticalHeader()->setSectionResizeMode(QHeaderView::Stretch);
    ui->inputTableWidget->verticalHeader()->hide();
    ui->inputTableWidget->setColumnCount(2);
    ui->inputTableWidget->setRowCount(1);
    ui->inputTableWidget->setHorizontalHeaderItem(0, new QTableWidgetItem(QCoreApplication::translate("dynamic", globalText.tableWidgetHeader[0])));
    ui->inputTableWidget->setHorizontalHeaderItem(1, new QTableWidgetItem(QCoreApplication::translate("dynamic", globalText.tableWidgetHeader[1])));
    ui->inputTableWidget->installEventFilter(this);
    ui->inputTableWidget->hide();

    // 商品表设置
    ui->tableWidget->setAttribute(Qt::WA_ShowWithoutActivating, true);
    ui->tableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
    ui->tableWidget->setColumnCount(4);
    ui->tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
    ui->tableWidget->setHorizontalHeaderItem(0, new QTableWidgetItem(QCoreApplication::translate("dynamic", globalText.tableWidgetHeader[0])));
    ui->tableWidget->setHorizontalHeaderItem(1, new QTableWidgetItem(QCoreApplication::translate("dynamic", globalText.tableWidgetHeader[1])));
    ui->tableWidget->setHorizontalHeaderItem(2, new QTableWidgetItem(QCoreApplication::translate("dynamic", globalText.tableWidgetHeader[2])));
    ui->tableWidget->setHorizontalHeaderItem(3, new QTableWidgetItem(QCoreApplication::translate("dynamic", globalText.tableWidgetHeader[3])));

    // 交易表设置
    ui->transactionTable->setAttribute(Qt::WA_ShowWithoutActivating, true);
    ui->transactionTable->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
    ui->transactionTable->setColumnCount(5);
    ui->transactionTable->setEditTriggers(QAbstractItemView::NoEditTriggers);
    ui->transactionTable->setHorizontalHeaderItem(0, new QTableWidgetItem(QCoreApplication::translate("dynamic", globalText.transactionTableHeader[0])));
    ui->transactionTable->setHorizontalHeaderItem(1, new QTableWidgetItem(QCoreApplication::translate("dynamic", globalText.transactionTableHeader[1])));
    ui->transactionTable->setHorizontalHeaderItem(2, new QTableWidgetItem(QCoreApplication::translate("dynamic", globalText.transactionTableHeader[2])));
    ui->transactionTable->setHorizontalHeaderItem(3, new QTableWidgetItem(QCoreApplication::translate("dynamic", globalText.transactionTableHeader[3])));
    ui->transactionTable->setHorizontalHeaderItem(4, new QTableWidgetItem(QCoreApplication::translate("dynamic", globalText.transactionTableHeader[4])));
    ui->transactionTable->horizontalHeader()->setSectionResizeMode(0, QHeaderView::ResizeToContents);

    ui->tabWidget->setCurrentIndex(settings.value("currentWidget").toInt());

    // 语言选择框
    ui->languageSwitch->clear();
    for (QHash<QString, QString>::const_iterator it = nameToQm.begin(); it != nameToQm.end(); ++it)
    {
        ui->languageSwitch->addItem(it.key());
    }
    QString language = settings.value("language").toString();
    ui->languageSwitch->setCurrentText(language);

    // 设置播放类
    player->setVolume(50);
    player->setPlaybackRate(1.0);

    // 设置语音播报
    tts->setLocale(nameToTtsLocal[language]);
    tts->setVolume(0.5);
    tts->setRate(0);

    // 水平话滑动条设置
    ui->pcVolume->setRange(0, 101);
    ui->pcVolume->setValue(settings.value("pcVolume").toInt());
    ui->pcVolume->setSingleStep(0);
    ui->pcVolume->setPageStep(0);
    ui->pcSpeed->setRange(0, 101);
    ui->pcSpeed->setValue(settings.value("pcSpeed").toInt());
    ui->pcSpeed->setSingleStep(5);
    ui->pcSpeed->setSingleStep(0);
    ui->pcSpeed->setPageStep(0);
    ui->mcuVolume->setRange(0, 101);
    ui->mcuVolume->setValue(settings.value("mcuVolume").toInt());
    ui->mcuVolume->setSingleStep(5);
    ui->mcuVolume->setSingleStep(0);
    ui->mcuVolume->setPageStep(0);
    ui->mcuSpeed->setRange(0, 101);
    ui->mcuSpeed->setValue(settings.value("mcuSPeed").toInt());
    ui->mcuSpeed->setSingleStep(5);
    ui->mcuSpeed->setSingleStep(0);
    ui->mcuSpeed->setPageStep(0);
    on_pcVolume_valueChanged(ui->pcVolume->value());
    on_pcSpeed_valueChanged(ui->pcSpeed->value());
    on_mcuVolume_sliderReleased();
    on_mcuSpeed_sliderReleased();

    QTimer* t1 = new QTimer(this);
    t1->start(500);
    QTimer* t2 = new QTimer(this);
    t2->start(1);

    connect(t1, &QTimer::timeout, this, &MainWindow::clearContents);
    connect(t2, &QTimer::timeout, this, &MainWindow::processBlueToothRecive);
    connect(bluetooth, &Bluetooth::deviceDiscovered, this, &MainWindow::addBlueToothDeviceToCombobox);
    connect(bluetooth, &Bluetooth::discoverError, this, &MainWindow::onDiscoverError);
    connect(bluetooth, &Bluetooth::connected, this, &MainWindow::blueToothConnected);
    connect(bluetooth, &Bluetooth::readyRead, this, &MainWindow::readSocketData);
    connect(bluetooth, &Bluetooth::socketError, this, &MainWindow::onSocketError);
    connect(ui->languageSwitch, QOverload<const QString&>::of(&QComboBox::currentIndexChanged), this, &MainWindow::switchLanguage);

    statusBarMessage->setText(QCoreApplication::translate("dynamic", globalText.welcome));
    tts->say(QCoreApplication::translate("dynamic", globalText.welcome));
    bluetooth->restart();
    disAbleEdit();
}

MainWindow::~MainWindow()
{
    delete ui;
    delete player;
    delete tts;
    delete bluetooth;
    delete socketBuf;
}

bool MainWindow::setTheme(const QString& qss)
{
    QFile styleFile(qss);
    styleFile.open(QIODevice::ReadOnly);
    if (!styleFile.isOpen())
    {
        return false;
    }
    qApp->setStyleSheet(styleFile.readAll());
    styleFile.close();
    return true;
}

void MainWindow::addTransactionRecord(const QString& dateTime, const QString& name, const QString& price, const QString& weight, const QString& total)
{
    ui->transactionTable->setRowCount(ui->transactionTable->rowCount() + 1);
    int lastRowIndex = ui->transactionTable->rowCount() - 1;
    ui->transactionTable->setItem(lastRowIndex, 0, new QTableWidgetItem(dateTime));
    ui->transactionTable->setItem(lastRowIndex, 1, new QTableWidgetItem(name));
    ui->transactionTable->setItem(lastRowIndex, 2, new QTableWidgetItem(price));
    ui->transactionTable->setItem(lastRowIndex, 3, new QTableWidgetItem(weight));
    ui->transactionTable->setItem(lastRowIndex, 4, new QTableWidgetItem(total));

    QString dirPath = transactionRecordConfig.value("dir").toString();
    if (dirPath.back() != '/')
    {
        dirPath += "/";
    }
    dirPath += ui->bluetooth_cb->currentText();
    dirPath.remove('|');
    dirPath.replace(':', '-');
    dirPath += "/";

    QDir dir(dirPath);
    if (!dir.exists())
    {
        dir.mkpath(".");
    }

    QString fileName = QDateTime::fromString(dateTime, "yyyy/M/d h:m:s").date().toString("yyyy-M-d");
    QDate currentDate = QDate::fromString(fileName, "yyyy-M-d");
    // 删除超过时间的记录文件
    int timeout = transactionRecordConfig.value("timeout").toInt();
    QFileInfoList files = dir.entryInfoList();
    for (const QFileInfo& file : files)
    {
        if (file.isFile())
        {
            QString tempFileName = file.baseName();
            if (QDate::fromString(tempFileName, "yyyy-M-d").daysTo(currentDate) > timeout)
            {
                QFile::remove(file.absoluteFilePath());
            }
        }
    }

    // 添加记录
    QXlsx::Document xlsx(dirPath + fileName + ".xlsx");
    xlsx.write("A1", "时间");
    xlsx.write("B1", "商品");
    xlsx.write("C1", "单价(y/kg)");
    xlsx.write("D1", "重量(kg)");
    xlsx.write("E1", "总价(y)");
    QXlsx::CellRange dimensions = xlsx.dimension();
    int rowIndex = dimensions.rowCount() + 1;
    xlsx.write(QString("A%1").arg(rowIndex), dateTime);
    xlsx.write(QString("B%1").arg(rowIndex), name);
    xlsx.write(QString("C%1").arg(rowIndex), price);
    xlsx.write(QString("D%1").arg(rowIndex), weight);
    xlsx.write(QString("E%1").arg(rowIndex), total);
    bool saveOk = xlsx.saveAs(dirPath + fileName + ".xlsx");
    if (!saveOk)
    {
        statusBarMessage->setText(QCoreApplication::translate("dynamic", globalText.failSave));
    }
}

// 处理蓝牙设备选择栏的点击信号
bool MainWindow::eventFilter(QObject* watched, QEvent* event)
{
    if (watched == ui->inputTableWidget)
    {
        if (event->type() == QEvent::KeyPress)
        {
            QKeyEvent* ke = dynamic_cast<QKeyEvent*>(event);
            if (ke->key() == Qt::Key_Escape)
            {
                ui->inputTableWidget->hide();
                ui->add_pb->setText(QCoreApplication::translate("dynamic", globalText.addGoos));
            }
            else if (ke->key() == Qt::Key_Return)
            {
                if (!ui->inputTableWidget->hasFocus())
                {
                    return true;
                }
                // 输入内容限制
                QTableWidgetItem *i1, *i2;
                i1 = ui->inputTableWidget->item(0, 0);
                i2 = ui->inputTableWidget->item(0, 1);
                player->setMedia(QMediaContent(QUrl("qrc:/music/error.mp3")));
                if (i1 == nullptr || i2 == nullptr)
                {
                    statusBarMessage->setText(QCoreApplication::translate("dynamic", globalText.failNameOrPrice));
                    player->play();
                    return true;
                }
                if (i1 != nullptr)
                {
                    QByteArray text = i1->text().toUtf8();
                    QString text1 = UTF82GBK(text);
                    int size = text1.toLocal8Bit().size();
                    if (size == 0 || size > 11)
                    {
                        statusBarMessage->setText(QCoreApplication::translate("dynamic", globalText.failName).arg(size));
                        player->play();
                        return true;
                    }
                }
                if (i2 != nullptr)
                {
                    QRegExp priceRegExp("^[0-9]{1,3}\\.[0-9]{1}$");
                    if (!priceRegExp.exactMatch(i2->text()))
                    {
                        statusBarMessage->setText(QCoreApplication::translate("dynamic", globalText.failPrice1));
                        player->play();
                        return true;
                    }
                    if (i2->text().toFloat() <= 0.0 || i2->text().toFloat() > 999)
                    {
                        statusBarMessage->setText(QCoreApplication::translate("dynamic", globalText.failPrice2));
                        player->play();
                        return true;
                    }
                }

                // 防止多次添加同一商品
                for (int i = 0; i < ui->tableWidget->rowCount(); ++i)
                {
                    if (ui->tableWidget->item(i, 0) == nullptr || ui->tableWidget->item(i, 1) == nullptr)
                    {
                        continue;
                    }
                    if (ui->tableWidget->item(i, 0)->text() == ui->inputTableWidget->item(0, 0)->text() && ui->tableWidget->item(i, 1)->text() == ui->inputTableWidget->item(0, 1)->text())
                    {
                        statusBarMessage->setText(QCoreApplication::translate("dynamic", globalText.failAdd));
                        player->play();
                        return true;
                    }
                }

                Goods goods;
                QTableWidgetItem* item;
                item = ui->inputTableWidget->item(0, 0);
                QByteArray name = item->text().toLocal8Bit();
                for (int i = 0; i < name.size(); ++i)
                {
                    goods.name[i] = name[i];
                }
                item = ui->inputTableWidget->item(0, 1);
                goods.price = item->text().toFloat();
                if (ui->inputTableWidget->item(0, 0) != nullptr)
                {
                    ui->inputTableWidget->item(0, 0)->setText("");
                }
                if (ui->inputTableWidget->item(0, 1) != nullptr)
                {
                    ui->inputTableWidget->item(0, 1)->setText("");
                }
                unsigned char buf[32];
                for (int i = 0; i < 12; ++i)
                {
                    buf[i] = goods.name[i];
                }
                unsigned char* ptr = reinterpret_cast<unsigned char*>(&goods.price);
                buf[12] = ptr[3];
                buf[13] = ptr[2];
                buf[14] = ptr[1];
                buf[15] = ptr[0];
                bluetooth->write(formatSendData(ADD_GOODS, buf, 16));
                ui->inputTableWidget->setFocus();
                ui->inputTableWidget->setCurrentCell(0, 0);
                ui->inputTableWidget->editItem(ui->inputTableWidget->item(0, 0));
                statusBarMessage->setText(QCoreApplication::translate("dynamic", globalText.addGoodsSucceed));
            }
        }
    }
    return QMainWindow::eventFilter(watched, event);
}

void MainWindow::paintEvent(QPaintEvent*)
{
    // 利用样式表设置下方切换块的大小
    int width = ui->tabWidget->width();
    int tabCount = ui->tabWidget->count();
    int tabWidth = width / tabCount;
    QString styleSheet = QString("QTabBar::tab { width : %1px; }").arg(tabWidth);
    ui->tabWidget->setStyleSheet(styleSheet);
}

bool MainWindow::nativeEvent(const QByteArray& eventType, void* message, long* result)
{
    // 禁用应用程序界面左上角的点击信号，这样点击左上角就不会弹出界面了
    MSG* msg = (MSG*)message;
    if (msg->message == WM_SYSCOMMAND)
    {
        if (msg->wParam == 61587) // 禁用单击
        {
            return true;
        }
        if (msg->wParam == 61539) // 禁用双击
        {
            return true;
        }
    }
    return QMainWindow::nativeEvent(eventType, message, result);
}

void MainWindow::closeEvent(QCloseEvent*)
{
    saveSettings();

    unsigned char sendBuf[64];
    QByteArray str = QString(globalText.disconnectBluetooth).toLocal8Bit();
    *(short*)(sendBuf) = str.size();
    std::swap(sendBuf[0], sendBuf[1]);
    for (int i = 0; i < str.size(); ++i)
    {
        sendBuf[2 + i] = str[i];
    }
    bluetooth->write(formatSendData(SPEECH_INFORMATION, sendBuf, 2 + str.size()));
}

void MainWindow::saveSettings()
{
    settings.setValue("pos", pos());
    settings.setValue("width", width());
    settings.setValue("height", height());
    settings.setValue("pcVolume", ui->pcVolume->value());
    settings.setValue("pcSpeed", ui->pcSpeed->value());
    settings.setValue("mcuVolume", ui->mcuVolume->value());
    settings.setValue("mcuSpeed", ui->mcuSpeed->value());
    settings.setValue("theme", currentTheme);
    settings.setValue("currentWidget", ui->tabWidget->currentIndex());
    settings.setValue("powersaving", ui->powerSaving->property("on").toBool());
}

void MainWindow::switchLanguage(const QString& arg1)
{
    settings.setValue("language", arg1);
    statusBarMessage->setText(QCoreApplication::translate("dynamic", globalText.languageSwitch));
}

void MainWindow::enableEdit()
{
    ui->Switch_pb->setEnabled(true);
    ui->Pre_pb->setEnabled(true);
    ui->Nex_pb->setEnabled(true);
    ui->Enter_pb->setEnabled(true);
    ui->add_pb->setEnabled(true);
    ui->refresh->setEnabled(false);

    ui->bluetoothLabel->setProperty("connected", 1);
    ui->bluetoothLabel->style()->polish(ui->bluetoothLabel);

    ui->tableWidget->setEnabled(false);
}

void MainWindow::disAbleEdit()
{
    ui->Switch_pb->setEnabled(false);
    ui->Pre_pb->setEnabled(false);
    ui->Nex_pb->setEnabled(false);
    ui->Enter_pb->setEnabled(false);
    ui->add_pb->setEnabled(false);
    ui->refresh->setEnabled(true);

    ui->lineEdit_0_0->clear();
    ui->lineEdit_0_1->clear();
    ui->lineEdit_0_2->clear();
    ui->lineEdit_0_3->clear();
    ui->lineEdit_0_4->clear();
    ui->lineEdit_0_5->clear();
    ui->lineEdit_0_6->clear();
    ui->lineEdit_0_7->clear();
    ui->lineEdit_0_8->clear();
    ui->lineEdit_0_9->clear();
    ui->lineEdit_0_10->clear();
    ui->lineEdit_0_11->clear();
    ui->lineEdit_0_12->clear();
    ui->lineEdit_0_13->clear();
    ui->lineEdit_0_14->clear();
    ui->lineEdit_0_15->clear();

    ui->lineEdit_1_0->clear();
    ui->lineEdit_1_1->clear();
    ui->lineEdit_1_2->clear();
    ui->lineEdit_1_3->clear();
    ui->lineEdit_1_4->clear();
    ui->lineEdit_1_5->clear();
    ui->lineEdit_1_6->clear();
    ui->lineEdit_1_7->clear();
    ui->lineEdit_1_8->clear();
    ui->lineEdit_1_9->clear();
    ui->lineEdit_1_10->clear();
    ui->lineEdit_1_11->clear();
    ui->lineEdit_1_12->clear();
    ui->lineEdit_1_13->clear();
    ui->lineEdit_1_14->clear();
    ui->lineEdit_1_15->clear();

    ui->lineEdit_2_0->clear();
    ui->lineEdit_2_1->clear();
    ui->lineEdit_2_2->clear();
    ui->lineEdit_2_3->clear();
    ui->lineEdit_2_4->clear();
    ui->lineEdit_2_5->clear();
    ui->lineEdit_2_6->clear();
    ui->lineEdit_2_7->clear();
    ui->lineEdit_2_8->clear();
    ui->lineEdit_2_9->clear();
    ui->lineEdit_2_10->clear();
    ui->lineEdit_2_11->clear();
    ui->lineEdit_2_12->clear();
    ui->lineEdit_2_13->clear();
    ui->lineEdit_2_14->clear();
    ui->lineEdit_2_15->clear();

    ui->lineEdit_3_0->clear();
    ui->lineEdit_3_1->clear();
    ui->lineEdit_3_2->clear();
    ui->lineEdit_3_3->clear();
    ui->lineEdit_3_4->clear();
    ui->lineEdit_3_5->clear();
    ui->lineEdit_3_6->clear();
    ui->lineEdit_3_7->clear();
    ui->lineEdit_3_8->clear();
    ui->lineEdit_3_9->clear();
    ui->lineEdit_3_10->clear();
    ui->lineEdit_3_11->clear();
    ui->lineEdit_3_12->clear();
    ui->lineEdit_3_13->clear();
    ui->lineEdit_3_14->clear();
    ui->lineEdit_3_15->clear();

    ui->lineEdit_0_15->setReadOnly(false);
    ui->lineEdit_1_15->setReadOnly(false);
    ui->lineEdit_2_15->setReadOnly(false);
    ui->lineEdit_3_15->setReadOnly(false);

    ui->tableWidget->setRowCount(0);
    ui->transactionTable->setRowCount(0);
    ui->inputTableWidget->hide();

    ui->bluetoothLabel->setProperty("connected", 0);
    ui->bluetoothLabel->style()->polish(ui->bluetoothLabel);

    disconnect(ui->tableWidget, &QTableWidget::itemDoubleClicked, this, &MainWindow::eidtItem);
    disconnect(ui->tableWidget, &QTableWidget::itemChanged, this, &MainWindow::setPrice);
}

void MainWindow::clearContents()
{
    if (!bluetooth->isConnected())
    {
        disAbleEdit();
    }
    if (!ui->inputTableWidget->isHidden())
    {
        ui->tableWidget->scrollToBottom();
    }
}

void MainWindow::addBlueToothDeviceToCombobox(const QBluetoothDeviceInfo& info)
{
    QString name = info.name() + " | " + info.address().toString();
    ui->bluetooth_cb->addItem(name);
}

void MainWindow::onSocketError(QBluetoothSocket::SocketError error)
{
    disAbleEdit();
    player->setMedia(QMediaContent(QUrl("qrc:/music/error.mp3")));
    player->play();
    if (error == QBluetoothSocket::ServiceNotFoundError)
    {
        statusBarMessage->setText(QCoreApplication::translate("dynamic", globalText.connectionFail));
    }
    else if (error == QBluetoothSocket::RemoteHostClosedError)
    {
        statusBarMessage->setText(QCoreApplication::translate("dynamic", globalText.connectionFail));
    }
    else
    {
        statusBarMessage->setText(QCoreApplication::translate("dynamic", globalText.socketError));
    }
    ui->bluetooth_cb->setEnabled(true);
    ui->connect_pb->setText(QCoreApplication::translate("dynamic", globalText.connect));
    bluetooth->disconnectDevice();
}

void MainWindow::onDiscoverError(QBluetoothDeviceDiscoveryAgent::Error)
{
    statusBarMessage->setText(QCoreApplication::translate("dynamic", globalText.discoveryError));
}

void MainWindow::blueToothConnected()
{
    statusBarMessage->setText(QCoreApplication::translate("dynamic", globalText.connectionSucceed));
    tts->say(QCoreApplication::translate("dynamic", globalText.connectionSucceed));
    player->setMedia(QMediaContent(QUrl("qrc:/music/BlueToothConnectionSuccessful.mp3")));
    player->play();
    enableEdit();
    ui->connect_pb->setText(QCoreApplication::translate("dynamic", globalText.disconnect));

    socketBuf->init();
    unsigned char sendBuf[64];
    bluetooth->write(formatSendData(GOODS_SIZE, sendBuf, 0));

    sendBuf[0] = static_cast<int>(!ui->powerSaving->property("on").toBool());
    bluetooth->write(formatSendData(POWERSAVING, sendBuf, 1));

    on_mcuVolume_sliderReleased();
    on_mcuSpeed_sliderReleased();

    QByteArray str = QString("蓝牙已连接").toLocal8Bit();
    *(short*)(sendBuf) = str.size();
    std::swap(sendBuf[0], sendBuf[1]);
    for (int i = 0; i < str.size(); ++i)
    {
        sendBuf[2 + i] = str[i];
    }
    bluetooth->write(formatSendData(SPEECH_INFORMATION, sendBuf, 2 + str.size()));

    statusBarMessage->setText(QCoreApplication::translate("dynamic", globalText.loadGoods));
}

void MainWindow::readSocketData()
{
    QByteArray dat = bluetooth->readAll();
    for (int i = 0; i < dat.size(); ++i)
    {
        socketBuf->write(dat.at(i));
    }
}

void MainWindow::processBlueToothRecive()
{
    unsigned char buf[128];
    for (int i = 0; i < 64; ++i)
    {
        static QSet<int> freqUsedSet;
        unsigned char command = formatReadData(socketBuf, buf);
        switch (command)
        {
        case NONE:
        {
        } break;
        case GOODS_SIZE:
        {
            std::swap(buf[0], buf[1]);
            short goodsSize = *reinterpret_cast<short*>(buf);
            ui->tableWidget->setRowCount(goodsSize);
        } break;
        case FREQUSED_GOODS_SIZE:
        {
            std::swap(buf[0], buf[1]);
        } break;
        case GOODS_INFORMATION:
        {
            std::swap(buf[0], buf[1]);
            short row = *reinterpret_cast<short*>(buf);
            QByteArray name;
            for (int i = 0; i < 12; ++i)
            {
                name += buf[2 + i];
            }
            std::swap(buf[14], buf[17]);
            std::swap(buf[15], buf[16]);
            float price = *reinterpret_cast<float*>(buf + 14);

            if (ui->tableWidget->rowCount() < row)
            {
                ui->tableWidget->setRowCount(row + 1);
            }
            if (ui->tableWidget->item(row, 0) == nullptr)
            {
                QTableWidgetItem* nameItem = new QTableWidgetItem;
                ui->tableWidget->setItem(row, 0, nameItem);
            }
            if (ui->tableWidget->item(row, 1) == nullptr)
            {
                QTableWidgetItem* priceItem = new QTableWidgetItem;
                ui->tableWidget->setItem(row, 1, priceItem);
            }
            if (ui->tableWidget->cellWidget(row, 2) == nullptr)
            {
                QPushButton* ckPb = new QPushButton;
                ckPb->setProperty("type", "freqUsed");
                ckPb->setProperty("isfreqUsed", false);
                ckPb->setStyle(ckPb->style());
                ui->tableWidget->setCellWidget(row, 2, ckPb);
                connect(ckPb, &QPushButton::clicked, this, &MainWindow::freqPb_toggeled);
            }
            if (ui->tableWidget->cellWidget(row, 3) == nullptr)
            {
                QPushButton* deletePb = new QPushButton;
                deletePb->setProperty("type", "delete");
                deletePb->setStyle(deletePb->style());
                ui->tableWidget->setCellWidget(row, 3, deletePb);
                connect(deletePb, &QPushButton::clicked, this, &MainWindow::remove_goods);
            }
            if (ui->tableWidget->item(row, 0) && ui->tableWidget->item(row, 1))
            {
                if (ui->tableWidget->item(row, 0)->text() != GBK2UTF8(name))
                {
                    ui->tableWidget->item(row, 0)->setText(GBK2UTF8(name));
                }
                if (ui->tableWidget->item(row, 1)->text() != QString::number(price, 'f', 1))
                {
                    ui->tableWidget->item(row, 1)->setText(QString::number(price, 'f', 1));
                }
                if (statusBarMessage->text() == QCoreApplication::translate("dynamic", globalText.loadGoods))
                {
                    ui->tableWidget->scrollToItem(ui->tableWidget->item(row, 0));
                }
            }
        } break;
        case FREQUSED_GOODS_INFORMATION:
        {
            std::swap(buf[0], buf[1]);
            short id = *reinterpret_cast<short*>(buf);
            std::swap(buf[2], buf[3]);
            short value = *reinterpret_cast<short*>(buf + 2);
            if (value >= 0 && value < ui->tableWidget->rowCount() && ui->tableWidget->cellWidget(value, 2) != nullptr)
            {
                freqUsedSet.insert(value);

                valueToId[value] = id;
                QPushButton* freqUsed = reinterpret_cast<QPushButton*>(ui->tableWidget->cellWidget(value, 2));
                freqUsed->setProperty("isfreqUsed", true);
                freqUsed->setStyle(freqUsed->style());
            }
        } break;
        case SHOW_INFORMATION:
        {
            for (int curRow = 0; curRow < 4; ++curRow)
            {
                QByteArray text;
                for (int i = 0; i < 16; ++i)
                {
                    text += buf[curRow * 16 + i];
                }
                QString utf8Text = GBK2UTF8(text.mid(0, 15));
                QString appText(15 - utf8Text.size(), QChar(' '));
                utf8Text += appText;
                if (curRow == 0)
                {
                    ui->lineEdit_0_0->setText(utf8Text.at(0));
                    ui->lineEdit_0_1->setText(utf8Text.at(1));
                    ui->lineEdit_0_2->setText(utf8Text.at(2));
                    ui->lineEdit_0_3->setText(utf8Text.at(3));
                    ui->lineEdit_0_4->setText(utf8Text.at(4));
                    ui->lineEdit_0_5->setText(utf8Text.at(5));
                    ui->lineEdit_0_6->setText(utf8Text.at(6));
                    ui->lineEdit_0_7->setText(utf8Text.at(7));
                    ui->lineEdit_0_8->setText(utf8Text.at(8));
                    ui->lineEdit_0_9->setText(utf8Text.at(9));
                    ui->lineEdit_0_10->setText(utf8Text.at(10));
                    ui->lineEdit_0_11->setText(utf8Text.at(11));
                    ui->lineEdit_0_12->setText(utf8Text.at(12));
                    ui->lineEdit_0_13->setText(utf8Text.at(13));
                    ui->lineEdit_0_14->setText(utf8Text.at(14));
                    ui->lineEdit_0_15->setText(QString(text.at(15)));
                }
                else if (curRow == 1)
                {
                    ui->lineEdit_1_0->setText(utf8Text.at(0));
                    ui->lineEdit_1_1->setText(utf8Text.at(1));
                    ui->lineEdit_1_2->setText(utf8Text.at(2));
                    ui->lineEdit_1_3->setText(utf8Text.at(3));
                    ui->lineEdit_1_4->setText(utf8Text.at(4));
                    ui->lineEdit_1_5->setText(utf8Text.at(5));
                    ui->lineEdit_1_6->setText(utf8Text.at(6));
                    ui->lineEdit_1_7->setText(utf8Text.at(7));
                    ui->lineEdit_1_8->setText(utf8Text.at(8));
                    ui->lineEdit_1_9->setText(utf8Text.at(9));
                    ui->lineEdit_1_10->setText(utf8Text.at(10));
                    ui->lineEdit_1_11->setText(utf8Text.at(11));
                    ui->lineEdit_1_12->setText(utf8Text.at(12));
                    ui->lineEdit_1_13->setText(utf8Text.at(13));
                    ui->lineEdit_1_14->setText(utf8Text.at(14));
                    ui->lineEdit_1_15->setText(QString(text.at(15)));
                    if (text.at(15) == 0x1e)
                    {
                        ui->lineEdit_1_15->setText(QString("▲"));
                    }
                }
                else if (curRow == 2)
                {
                    ui->lineEdit_2_0->setText(utf8Text.at(0));
                    ui->lineEdit_2_1->setText(utf8Text.at(1));
                    ui->lineEdit_2_2->setText(utf8Text.at(2));
                    ui->lineEdit_2_3->setText(utf8Text.at(3));
                    ui->lineEdit_2_4->setText(utf8Text.at(4));
                    ui->lineEdit_2_5->setText(utf8Text.at(5));
                    ui->lineEdit_2_6->setText(utf8Text.at(6));
                    ui->lineEdit_2_7->setText(utf8Text.at(7));
                    ui->lineEdit_2_8->setText(utf8Text.at(8));
                    ui->lineEdit_2_9->setText(utf8Text.at(9));
                    ui->lineEdit_2_10->setText(utf8Text.at(10));
                    ui->lineEdit_2_11->setText(utf8Text.at(11));
                    ui->lineEdit_2_12->setText(utf8Text.at(12));
                    ui->lineEdit_2_13->setText(utf8Text.at(13));
                    ui->lineEdit_2_14->setText(utf8Text.at(14));
                    ui->lineEdit_2_15->setText(QString(text.at(15)));
                }
                else
                {
                    ui->lineEdit_3_0->setText(utf8Text.at(0));
                    ui->lineEdit_3_1->setText(utf8Text.at(1));
                    ui->lineEdit_3_2->setText(utf8Text.at(2));
                    ui->lineEdit_3_3->setText(utf8Text.at(3));
                    ui->lineEdit_3_4->setText(utf8Text.at(4));
                    ui->lineEdit_3_5->setText(utf8Text.at(5));
                    ui->lineEdit_3_6->setText(utf8Text.at(6));
                    ui->lineEdit_3_7->setText(utf8Text.at(7));
                    ui->lineEdit_3_8->setText(utf8Text.at(8));
                    ui->lineEdit_3_9->setText(utf8Text.at(9));
                    ui->lineEdit_3_10->setText(utf8Text.at(10));
                    ui->lineEdit_3_11->setText(utf8Text.at(11));
                    ui->lineEdit_3_12->setText(utf8Text.at(12));
                    ui->lineEdit_3_13->setText(utf8Text.at(13));
                    ui->lineEdit_3_14->setText(utf8Text.at(14));
                    ui->lineEdit_3_15->setText(QString(text.at(15)));
                    if (text.at(15) == 0x1f)
                    {
                        ui->lineEdit_3_15->setText(QString("▼"));
                    }
                }
            }
        } break;
        case REVER_ROW:
        {
            std::swap(buf[0], buf[1]);
            short reverRow = *reinterpret_cast<short*>(buf);
            ui->lineEdit_0_15->setReadOnly(false);
            ui->lineEdit_1_15->setReadOnly(false);
            ui->lineEdit_2_15->setReadOnly(false);
            ui->lineEdit_3_15->setReadOnly(false);
            if (reverRow == 0)
            {
                ui->lineEdit_0_15->setReadOnly(true);
            }
            else if (reverRow == 1)
            {
                ui->lineEdit_1_15->setReadOnly(true);
            }
            else if (reverRow == 2)
            {
                ui->lineEdit_2_15->setReadOnly(true);
            }
            else
            {
                ui->lineEdit_3_15->setReadOnly(true);
            }
        } break;
        case SPEECH_INFORMATION:
        {
            std::swap(buf[0], buf[1]);
            short n = *reinterpret_cast<short*>(buf);
            QByteArray text;
            for (int i = 0; i < n; ++i)
            {
                text += buf[2 + i];
            }
            tts->say(GBK2UTF8(text));
        } break;
        case FREQUSED_GOODS_OK:
        {
            std::swap(buf[0], buf[1]);
            short freqUsedSize = *(short*)(buf);
            if (freqUsedSet.size() == freqUsedSize && statusBarMessage->text() == QCoreApplication::translate("dynamic", globalText.loadGoods))
            {
                ui->tableWidget->setEnabled(true);
                statusBarMessage->setText(QCoreApplication::translate("dynamic", globalText.loadGoodsOK));
                connect(ui->tableWidget, &QTableWidget::itemDoubleClicked, this, &MainWindow::eidtItem);
                connect(ui->tableWidget, &QTableWidget::itemChanged, this, &MainWindow::setPrice);
            }
            if (freqUsedSet.size() == freqUsedSize)
            {
                for (int row = 0; row < ui->tableWidget->rowCount(); ++row)
                {
                    if (freqUsedSet.find(row) == freqUsedSet.end())
                    {
                        if (ui->tableWidget->cellWidget(row, 2) != nullptr)
                        {
                            QPushButton* freqUsed = reinterpret_cast<QPushButton*>(ui->tableWidget->cellWidget(row, 2));
                            freqUsed->setProperty("isfreqUsed", false);
                            freqUsed->setStyle(freqUsed->style());
                        }
                    }
                }
            }
            freqUsedSet.clear();
        } break;
        case REMOVE_GOODS_OK:
        {
            std::swap(buf[0], buf[1]);
            short row = *(short*)(buf);
            if (row < ui->tableWidget->rowCount())
            {
                ui->tableWidget->removeRow(row);
                statusBarMessage->setText(QCoreApplication::translate("dynamic", globalText.removeGoods));
            }
        } break;
        case REMOVE_FREQUSED_GODOS_OK:
        {
            std::swap(buf[0], buf[1]);
            short row = *(short*)(buf);
            if (row < ui->tableWidget->rowCount())
            {
                if (ui->tableWidget->cellWidget(row, 2) != nullptr)
                {
                    QPushButton* freqUsed = reinterpret_cast<QPushButton*>(ui->tableWidget->cellWidget(row, 2));
                    freqUsed->setProperty("isfreqUsed", false);
                    freqUsed->setStyle(freqUsed->style());
                    statusBarMessage->setText(QCoreApplication::translate("dynamic", globalText.removeFreqGoods));
                }
            }
        } break;
        case TRANSACTION_RECORD:
        {
            QString dateTime = QDateTime::currentDateTime().toString("yyyy/M/d h:m:s");
            QByteArray name;
            for (int i = 0; i < 12; ++i)
            {
                name += buf[i];
            }
            std::swap(buf[12], buf[15]);
            std::swap(buf[13], buf[14]);
            float price = *reinterpret_cast<float*>(buf + 12);
            std::swap(buf[16], buf[19]);
            std::swap(buf[17], buf[18]);
            float weight = *reinterpret_cast<float*>(buf + 16);
            std::swap(buf[20], buf[23]);
            std::swap(buf[21], buf[22]);
            float total = *reinterpret_cast<float*>(buf + 20);
            addTransactionRecord(dateTime, GBK2UTF8(name), QString::number(price, 'f', 1), QString::number(weight, 'f', 3), QString::number(total, 'f', 2));
        } break;
        case CLEAR_AMOUNT:
        {
            QString dateTime = QDateTime::currentDateTime().toString("yyyy/M/d h:m:s");
            addTransactionRecord(dateTime, "####", "####", "####", "####");
        } break;
        default:
        {
        } break;
        }
    }
}

void MainWindow::remove_goods()
{
    player->setMedia(QMediaContent(QUrl("qrc:/music/button.mp3")));
    player->play();
    if (ui->tableWidget->rowCount() <= 1)
    {
        statusBarMessage->setText(QCoreApplication::translate("dynamic", globalText.leastOneGoods));
        return;
    }
    short row = ui->tableWidget->currentRow();
    if (row == -1)
    {
        statusBarMessage->setText(QCoreApplication::translate("dynamic", globalText.pleaseChooseGoods));
        return;
    }

    int cnt = 0, rowId = 0;
    for (int row = 0; row < ui->tableWidget->rowCount(); ++row)
    {
        if (ui->tableWidget->cellWidget(row, 2) != nullptr)
        {
            QPushButton* freqUsed = reinterpret_cast<QPushButton*>(ui->tableWidget->cellWidget(row, 2));
            if (freqUsed->property("isfreqUsed").toBool())
            {
                ++cnt;
                rowId = row;
                if (cnt >= 2)
                {
                    break;
                }
            }
        }
    }
    if (cnt == 1 && rowId == row)
    {
        statusBarMessage->setText(QCoreApplication::translate("dynamic", globalText.leastOneFreqUsedGoods));
        return;
    }

    qDebug() << "remove goods " << row;
    unsigned char sendBuf[8];
    *(short*)(sendBuf) = row;
    std::swap(sendBuf[0], sendBuf[1]);
    bluetooth->write(formatSendData(REMOVE_GOODS, sendBuf, 2));
}

void MainWindow::add_freq()
{
    player->setMedia(QMediaContent(QUrl("qrc:/music/button.mp3")));
    player->play();
    short row = ui->tableWidget->currentRow();
    if (row == -1)
    {
        statusBarMessage->setText(QCoreApplication::translate("dynamic", globalText.pleaseChooseGoods));
        return;
    }
    if (row < ui->tableWidget->rowCount())
    {
        if (ui->tableWidget->cellWidget(row, 2) == nullptr)
        {
            return;
        }
        if (ui->tableWidget->cellWidget(row, 2) != nullptr)
        {
            QPushButton* freqUsed = reinterpret_cast<QPushButton*>(ui->tableWidget->cellWidget(row, 2));
            if (freqUsed->property("isfreqUsed").toBool())
            {
                return;
            }
        }
    }

    qDebug() << "add freqUsedGoods " << row;
    unsigned char sendBuf[8];
    *(short*)(sendBuf) = row;
    std::swap(sendBuf[0], sendBuf[1]);
    bluetooth->write(formatSendData(ADD_FREQUSED_GOODS, sendBuf, 2));
    statusBarMessage->setText(QCoreApplication::translate("dynamic", globalText.addFreqGoods));
}

void MainWindow::remove_freq()
{
    player->setMedia(QMediaContent(QUrl("qrc:/music/button.mp3")));
    player->play();
    short row = ui->tableWidget->currentRow();
    if (row == -1)
    {
        statusBarMessage->setText(QCoreApplication::translate("dynamic", globalText.pleaseChooseGoods));
        return;
    }
    int cnt = 0;
    for (int row = 0; row < ui->tableWidget->rowCount(); ++row)
    {
        if (ui->tableWidget->cellWidget(row, 2) != nullptr)
        {
            QPushButton* freqUsed = reinterpret_cast<QPushButton*>(ui->tableWidget->cellWidget(row, 2));
            if (freqUsed->property("isfreqUsed").toBool())
            {
                ++cnt;
                if (cnt >= 2)
                {
                    break;
                }
            }
        }
    }
    if (cnt == 1)
    {
        statusBarMessage->setText(QCoreApplication::translate("dynamic", globalText.leastOneFreqUsedGoods));
        return;
    }
    if (row < ui->tableWidget->rowCount())
    {
        if (ui->tableWidget->cellWidget(row, 2) == nullptr)
        {
            return;
        }
        if (ui->tableWidget->cellWidget(row, 2) != nullptr)
        {
            QPushButton* freqUsed = reinterpret_cast<QPushButton*>(ui->tableWidget->cellWidget(row, 2));
            if (!freqUsed->property("isfreqUsed").toBool())
            {
                return;
            }
        }
    }

    qDebug() << "remove freqUsedGoods " << valueToId[row];
    unsigned char sendBuf[8];
    *(short*)(sendBuf) = valueToId[row];
    std::swap(sendBuf[0], sendBuf[1]);
    bluetooth->write(formatSendData(REMOVE_FSREQUSED_GOODS, sendBuf, 2));
}

void MainWindow::freqPb_toggeled()
{
    int row = ui->tableWidget->currentRow();
    if (row == -1 || ui->tableWidget->cellWidget(row, 2) == nullptr)
    {
        return;
    }
    if (!ui->tableWidget->cellWidget(row, 2)->property("isfreqUsed").toBool())
    {
        add_freq();
    }
    else
    {
        remove_freq();
    }
}

void MainWindow::eidtItem(QTableWidgetItem* item)
{
    int column = item->column();
    if (column != 1)
    {
        return;
    }
    ui->tableWidget->editItem(item);
}

void MainWindow::setPrice(QTableWidgetItem* item)
{
    int column = item->column();
    if (column != 1)
    {
        return;
    }
    player->setMedia(QMediaContent(QUrl("qrc:/music/error.mp3")));
    QRegExp priceRegExp("^[0-9]{1,3}\\.[0-9]{1}$");
    if (!priceRegExp.exactMatch(item->text()))
    {
        statusBarMessage->setText(QCoreApplication::translate("dynamic", globalText.failPrice1));
        player->play();
        ui->tableWidget->editItem(item);
        return;
    }
    if (item->text().toFloat() <= 0.0 || item->text().toFloat() > 999)
    {
        statusBarMessage->setText(QCoreApplication::translate("dynamic", globalText.failPrice2));
        player->play();
        ui->tableWidget->editItem(item);
        return;
    }
    short row = item->row();
    float price = item->text().toFloat();
    unsigned char sendBuf[8];
    *(short*)(sendBuf) = row;
    std::swap(sendBuf[0], sendBuf[1]);
    *(float*)(sendBuf + 2) = price;
    std::swap(sendBuf[2], sendBuf[5]);
    std::swap(sendBuf[3], sendBuf[4]);
    bluetooth->write(formatSendData(SET_PRICE, sendBuf, 6));
}

void MainWindow::on_connect_pb_clicked()
{
    bluetooth->stop();
    if (ui->connect_pb->text() == QCoreApplication::translate("dynamic", globalText.connect))
    {
        ui->refresh->setEnabled(false);
        tts->say(QCoreApplication::translate("dynamic", globalText.bluetoothConnection));
        statusBarMessage->setText(QCoreApplication::translate("dynamic", globalText.bluetoothConnection));
        // 得到蓝牙设备名称和地址
        QString str = ui->bluetooth_cb->currentText();
        int id = str.lastIndexOf(' ');
        QString name = str.mid(0, id);
        QBluetoothAddress addr(str.mid(id + 1));
        if (addr.isNull())
        {
            player->setMedia(QMediaContent(QUrl("qrc:/music/error.mp3")));
            player->play();
            statusBarMessage->setText(QCoreApplication::translate("dynamic", globalText.failName));
            return;
        }
        // 利用 socket 对象建立蓝牙通信
        bluetooth->connectDevice(addr, QBluetoothUuid(Bluetooth::serviceUuid), QIODevice::ReadWrite);
        ui->bluetooth_cb->setEnabled(false);
        ui->connect_pb->setText(QCoreApplication::translate("dynamic", globalText.cancelConnect));
    }
    else if (ui->connect_pb->text() == QCoreApplication::translate("dynamic", globalText.cancelConnect))
    {
        disAbleEdit();
        statusBarMessage->setText(QCoreApplication::translate("dynamic", globalText.cancelConnect));
        bluetooth->disconnectDevice();
        ui->connect_pb->setText(QCoreApplication::translate("dynamic", globalText.connect));
        ui->bluetooth_cb->setEnabled(true);
    }
    else
    { // 断开连接
        disAbleEdit();

        unsigned char sendBuf[64];
        QByteArray str = QString(globalText.disconnectBluetooth).toLocal8Bit();
        *(short*)(sendBuf) = str.size();
        std::swap(sendBuf[0], sendBuf[1]);
        for (int i = 0; i < str.size(); ++i)
        {
            sendBuf[2 + i] = str[i];
        }
        bluetooth->write(formatSendData(SPEECH_INFORMATION, sendBuf, 2 + str.size()));

        socketBuf->init();
        statusBarMessage->setText(QCoreApplication::translate("dynamic", globalText.disconnectBluetooth));
        bluetooth->disconnectDevice();
        ui->connect_pb->setText(QCoreApplication::translate("dynamic", globalText.connect));
        statusBarMessage->setText(QCoreApplication::translate("dynamic", globalText.disconnectBluetooth));
        ui->bluetooth_cb->setEnabled(true);
        bluetooth->disconnectDevice();
        tts->say(QCoreApplication::translate("dynamic", globalText.disconnectBluetooth));
    }
}

void MainWindow::on_Switch_pb_clicked()
{
    player->setMedia(QMediaContent(QUrl("qrc:/music/button.mp3")));
    player->play();
    unsigned char sendBuf[8];
    sendBuf[0] = 0x01;
    bluetooth->write(formatSendData(KEY_OP, sendBuf, 1));
}

void MainWindow::on_Pre_pb_clicked()
{
    player->setMedia(QMediaContent(QUrl("qrc:/music/button.mp3")));
    player->play();
    unsigned char sendBuf[8];
    sendBuf[0] = 0x02;
    bluetooth->write(formatSendData(KEY_OP, sendBuf, 1));
}

void MainWindow::on_Nex_pb_clicked()
{
    player->setMedia(QMediaContent(QUrl("qrc:/music/button.mp3")));
    player->play();
    unsigned char sendBuf[8];
    sendBuf[0] = 0x04;
    bluetooth->write(formatSendData(KEY_OP, sendBuf, 1));
}

void MainWindow::on_Enter_pb_clicked()
{
    player->setMedia(QMediaContent(QUrl("qrc:/music/button.mp3")));
    player->play();
    unsigned char sendBuf[8];
    sendBuf[0] = 0x08;
    bluetooth->write(formatSendData(KEY_OP, sendBuf, 1));
}

void MainWindow::on_add_pb_clicked()
{
    player->setMedia(QMediaContent(QUrl("qrc:/music/button.mp3")));
    player->play();
    if (ui->add_pb->text() == QCoreApplication::translate("dynamic", globalText.addGoos))
    {
        if (ui->tableWidget->rowCount() == 256)
        {
            return;
        }
        if (ui->inputTableWidget->item(0, 0) != nullptr)
        {
            ui->inputTableWidget->item(0, 0)->setText("");
        }
        if (ui->inputTableWidget->item(0, 1) != nullptr)
        {
            ui->inputTableWidget->item(0, 1)->setText("");
        }
        ui->inputTableWidget->setFocus();
        ui->inputTableWidget->setCurrentCell(0, 0);
        ui->inputTableWidget->editItem(ui->inputTableWidget->item(0, 0));
        ui->inputTableWidget->show();
        ui->add_pb->setText(QCoreApplication::translate("dynamic", globalText.cancelAddGoos));
    }
    else
    {
        ui->inputTableWidget->hide();
        ui->add_pb->setText(QCoreApplication::translate("dynamic", globalText.addGoos));
    }
}

void MainWindow::on_search_returnPressed()
{
    QString ruler = QString(".*%1.*").arg(ui->search->text());
    QRegExp regex(ruler);
    int row = ui->tableWidget->rowCount();
    for (int i = 0; i < row; ++i)
    {
        if (!regex.exactMatch(ui->tableWidget->item(i, 0)->text()))
        {
            ui->tableWidget->setRowHidden(i, true);
        }
    }
}

void MainWindow::on_search_textChanged(const QString& arg1)
{
    if (arg1.size() == 0)
    {
        int row = ui->tableWidget->rowCount();
        for (int i = 0; i < row; ++i)
        {
            ui->tableWidget->setRowHidden(i, false);
        }
    }
}

void MainWindow::on_pcVolume_valueChanged(int value)
{
    tts->setVolume(value / 100.0); // 0.0 ~ 1.0
    player->setVolume(value); // 0 ~ 100
}

void MainWindow::on_pcSpeed_valueChanged(int value)
{
    tts->setRate((value - 50) / 50.0); // -1.0 ~ 1.0
    player->setPlaybackRate(value / 50.0); // default 1.0
}

void MainWindow::on_mcuVolume_sliderReleased()
{
    unsigned char buf[8];
    buf[0] = (16 / 100.0 * ui->mcuVolume->value());
    bluetooth->write(formatSendData(SET_TTS_VOLUMN, buf, 1));
}

void MainWindow::on_mcuSpeed_sliderReleased()
{
    unsigned char buf[8];
    buf[0] = (5 / 100.0 * ui->mcuVolume->value());
    bluetooth->write(formatSendData(SET_TTS_RATE, buf, 1));
}

void MainWindow::on_selectTheme_clicked()
{
    QString themeFileName = QFileDialog::getOpenFileName(this, QCoreApplication::translate("dynamic", globalText.themeSelect), QDir::homePath(), QCoreApplication::translate("dynamic", globalText.themeFilter));
    if (themeFileName == "")
    {
        return;
    }
    setTheme(themeFileName);
}

void MainWindow::on_blue_clicked()
{
    setTheme(":/style/blue.qss");
    currentTheme = ":/style/blue.qss";
}

void MainWindow::on_red_clicked()
{
    setTheme(":/style/red.qss");
    currentTheme = ":/style/red.qss";
}

void MainWindow::on_green_clicked()
{
    setTheme(":/style/green.qss");
    currentTheme = ":/style/green.qss";
}

void MainWindow::on_refresh_clicked()
{
    statusBarMessage->setText(QCoreApplication::translate("dynamic", globalText.connecting));
    ui->bluetooth_cb->clear();
    bluetooth->restart();
}


void MainWindow::on_searchTransaction_textChanged(const QString& arg1)
{
    if (arg1.size() == 0)
    {
        int row = ui->transactionTable->rowCount();
        for (int i = 0; i < row; ++i)
        {
            ui->transactionTable->setRowHidden(i, false);
        }
    }
}

void MainWindow::on_searchTransaction_returnPressed()
{
    QString ruler = QString(".*%1.*").arg(ui->searchTransaction->text());
    QRegExp regex(ruler);
    int row = ui->transactionTable->rowCount();
    for (int i = 0; i < row; ++i)
    {
        if (!regex.exactMatch(ui->transactionTable->item(i, 1)->text()))
        {
            ui->transactionTable->setRowHidden(i, true);
        }
    }
}

void MainWindow::on_powerSaving_clicked()
{
    bool newValue = !ui->powerSaving->property("on").toBool();
    ui->powerSaving->setProperty("on", newValue);
    ui->powerSaving->setStyle(ui->powerSaving->style());

    unsigned char buf[8];
    buf[0] = static_cast<int>(newValue);
    bluetooth->write(formatSendData(POWERSAVING, buf, 1));
}
